
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.behaviors.vp.*;
import javax.swing.JFrame;
import java.util.*;

/**
* Eine Klasse (Thread) zur Erzeugung einzelner Partikel, 
* die sich nach Ablauf ihrer Lebensdauer wieder selbst 
* zerstoeren (aus dem Szenengraphen loeschen).
*
* @author Frank Klawonn
* Letzte Aenderung 1.8.2008
*
*/
public class SimpleSingleParticleCreator extends Thread
{
  //Das zugehoerige Partikelsystem
  public SimpleParticleSystem ps;

  //Die BranchGroup, der alle Partikel zugeordnet werden, die wiederum einer
  //Transformationsgruppe im Szenengraphen zugeordnet ist.
  public BranchGroup bg;


  /**
  * Konstruktor
  *
  * @param partSys   Das zugehoerige Partikelsystem
  * @param bGroup    Die BranchGroup, der alle Partikel zugeordnet werden
  */
  public SimpleSingleParticleCreator(SimpleParticleSystem partSys, BranchGroup bGroup)
  {
    ps = partSys;
    bg = bGroup;
  }



  // Hier wird das Partikel zusammen mit seiner Bewegung erzeugt und nach Ablauf seiner Lebensdauer 
  //wieder geloescht.
  public void run()
  {
    //Das Partikel
    TransformGroup tgParticle = ps.particleCreator.getNextParticle();


    //Die Bewegung des Partikels entlang der x-Achse
    TransformGroup tgmParticle = new TransformGroup();
    tgmParticle.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

    tgmParticle.addChild(tgParticle);

    //Die Lebesdauer des Partikels
    long lifeSpan = ps.lifeSpan.getNextLong();
 
    //Die Geschwindigkeit des Partikels
    float velocity = ps.velocity.getNextFloat();


    //Die Bewegung des Partikels wird berechnet und in einer Transformationsgruppe realsiert.
    //Die Bewegung findet zunaechst entlang der x-Achse statt und wird dann entsprechend positioniert. 

    //Die Endposition des Partikels (auf der x-Achse) am Ende seiner Lebensdauer
    float endPosition = (lifeSpan*velocity)/1000.0f;

    //Das Alpha fuer die Bewegung
    Alpha particleAlpha = new Alpha(1,Alpha.INCREASING_ENABLE,0,0,lifeSpan,0,0,0,0,0);
    particleAlpha.setStartTime(System.currentTimeMillis()-particleAlpha.getTriggerTime());

    Transform3D axis = new Transform3D();
    PositionInterpolator posIPParticle = new PositionInterpolator(particleAlpha,
                                                   tgmParticle,axis,
                                                   0.0f,endPosition);

    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0),Double.MAX_VALUE);
    posIPParticle.setSchedulingBounds(bounds);

    tgmParticle.addChild(posIPParticle);


    //Die Transformationsgruppe, um das Partikel auf seine Anfangsposition zu setzen und 
    //die Bewegung in die gewuenschte Richtung auszufuehren.
    Transform3D tfPositioning = new Transform3D();

    tfPositioning.setTranslation(ps.startPosition.getNextVector3f());

    Transform3D tfRotY = new Transform3D();
    tfRotY.rotY(ps.direction.getNextYRotation());

    Transform3D tfRotZ = new Transform3D();
    tfRotZ.rotZ(ps.direction.getNextZRotation());

    tfPositioning.mul(tfRotY);
    tfPositioning.mul(tfRotZ);

    TransformGroup tgPositioning = new TransformGroup(tfPositioning);

    tgPositioning.addChild(tgmParticle);


    //Die Branchgruppe des Partikels mit Positionierung und Bewegung
    BranchGroup bgSingleParticle = new BranchGroup();
    bgSingleParticle.setCapability(BranchGroup.ALLOW_DETACH);
    bgSingleParticle.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
    bgSingleParticle.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
    bgSingleParticle.setCapability(BranchGroup.ALLOW_CHILDREN_READ);

    bgSingleParticle.addChild(tgPositioning);


    bg.addChild(bgSingleParticle);


    //Nach Ablauf der Lebensdauer wird das Partikel bzw. seine Branchgroup wieder geloescht
    try
    {
      sleep(lifeSpan);
    }
    catch(InterruptedException e)
    {
      System.out.println("Error");
    }

    bg.removeChild(bgSingleParticle);


  }







}
